﻿#include "MaterialHyperelasticWidget.h"
#include "ui_MaterialHyperelasticWidget.h"
#include "FITK_Component/FITKWidget/FITKTableWidget.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaMaterialBehavior.h"

#include <QStringList>
#include <QButtonGroup>
#include <QMessageBox>

namespace GUI {
    MaterialHyperelasticWidget::MaterialHyperelasticWidget(EventOper::ParaWidgetInterfaceOperator * oper,Interface::FITKAbaMaterialHyperElastic * item, QWidget * parent) :
        MaterialWidgetBase(oper,parent), _materialItem(item)
    {
        _ui = new Ui::MaterialHyperelasticWidget();
        _ui->setupUi(this);

        initUi();
    }

    MaterialHyperelasticWidget::~MaterialHyperelasticWidget()
    {
        if (_ui != nullptr)delete _ui;
    }

    bool MaterialHyperelasticWidget::checkValue()
    {
        auto checkValue = [=](QString str, int row, int column)->bool {
            //判断数据是否有效
            bool isOk = false;
            str.toDouble(&isOk);
            if (isOk == true)return true;

            QString message = QString(tr("Tabular data for at least one option or suboption\n has either blank or zero valued row(s).\n"));
            message = message + QString(tr("Error: Hyperelastic row: %1\n").arg(row + 1));
            message = message + QString(tr("Error: Hyperelastic column: %1\n").arg(column + 1));
            QMessageBox::warning(this, tr("StructualApp"), message);
            return false;
        };

        int rowNum = _ui->tableWidget_MooRiv->rowCount();
        int colNum = _ui->tableWidget_MooRiv->columnCount();
        bool isTemp = _ui->checkBox_Temp->isChecked();
        _ui->tableWidget_MooRiv->setEnabled(false);
        _ui->tableWidget_MooRiv->setEnabled(true);
        for (int i = 0; i < rowNum; i++) {
            for (int j = 0; j < colNum; j++) {
                QString value = "";
                QTableWidgetItem* item = _ui->tableWidget_MooRiv->item(i, j);
                if (item == nullptr)continue;
                value = item->text();

                if (isTemp == false && j == 3) {
                    continue;
                }
                else {
                    if (!checkValue(value, i, j))return false;
                }
            }
        }

        return true;
    }

    bool MaterialHyperelasticWidget::saveValue()
    {
        if (_materialItem == nullptr)return false;

        if (_ui->radioButton_Isotropic->isChecked()) {
            _materialItem->setMaterialType(Interface::FITKAbaMaterialBehaviorEnum::HyperelasticMaterialType::HyereIsotropic);
            saveValueIso();
        }
        else {
            _materialItem->setMaterialType(Interface::FITKAbaMaterialBehaviorEnum::HyperelasticMaterialType::HyereAnisotropic);
            saveValueAni();
        }

        return true;
    }

    void MaterialHyperelasticWidget::on_checkBox_Temp_clicked(bool checked)
    {
        Interface::FITKAbaMaterialBehaviorEnum::HyperelasticIsotropicStrainEnergyPotential type;
        int index = _ui->comboBox_StrEnePot->currentIndex();
        switch (index) {
        case 0:type = Interface::FITKAbaMaterialBehaviorEnum::ArrudaBoyce; break;
        case 1:type = Interface::FITKAbaMaterialBehaviorEnum::Marlow; break;
        case 2:type = Interface::FITKAbaMaterialBehaviorEnum::MooneyRivlin; break;
        case 3:type = Interface::FITKAbaMaterialBehaviorEnum::NeoHooke; break;
        case 4:type = Interface::FITKAbaMaterialBehaviorEnum::Ogden; break;
        case 5:type = Interface::FITKAbaMaterialBehaviorEnum::Polynomial; break;
        case 6:type = Interface::FITKAbaMaterialBehaviorEnum::ReducePolynomial; break;
        case 7:type = Interface::FITKAbaMaterialBehaviorEnum::UsrDefined; break;
        case 8:type = Interface::FITKAbaMaterialBehaviorEnum::VanderWaals; break;
        case 9:type = Interface::FITKAbaMaterialBehaviorEnum::Yeoh; break;
        case 10:type = Interface::FITKAbaMaterialBehaviorEnum::Unknown; break;
        }

        changeMaterialTemp(type, checked);
    }

    void MaterialHyperelasticWidget::saveValueIso()
    {
        //判断是否使用测试数据
        if (_ui->radioButton_TestData->isChecked()) {
            _materialItem->setIsoInputSource(Interface::FITKAbaMaterialBehaviorEnum::HyperelasticIsotropicInputSource::TestData);
            //存储测试数据
            saveValueIsoTestData();
        }
        else {
            //存储系数数据
            _materialItem->setIsoInputSource(Interface::FITKAbaMaterialBehaviorEnum::HyperelasticIsotropicInputSource::Coeffcients);
            saveValueIsoCoefficients();
        }
    }

    void MaterialHyperelasticWidget::saveValueIsoTestData()
    {
    }

    void MaterialHyperelasticWidget::saveValueIsoCoefficients()
    {
        int strEnePotIndex = _ui->comboBox_StrEnePot->currentIndex();
        switch (strEnePotIndex) {
        case 0:break;
        case 1:break;
            //Mooney-Rivlin
        case 2: {
            //各向同性应变势能类型
            _materialItem->setIsoStrainEnergyPotential(Interface::FITKAbaMaterialBehaviorEnum::HyperelasticIsotropicStrainEnergyPotential::MooneyRivlin);

            //设置各向同性Moduli Time Scale
            int modTimeIndex = _ui->comboBox_ModTimeSca->currentIndex();
            switch (modTimeIndex) {
            case 0:_materialItem->setIsoModuliTimeScale(Interface::FITKAbaMaterialBehaviorEnum::HyperelasticIsoModuliTimeScale::LongTerm); break;
            case 1:_materialItem->setIsoModuliTimeScale(Interface::FITKAbaMaterialBehaviorEnum::HyperelasticIsoModuliTimeScale::Instantaneous); break;
            }

            //设置参数是否随温度变化
            bool isTemp = _ui->checkBox_Temp->isChecked();
            _materialItem->setUseTemperatureDependentData(isTemp);

            int rowNum = _ui->tableWidget_MooRiv->rowCount();
            int colNum = _ui->tableWidget_MooRiv->columnCount();
            for (int i = 0; i < rowNum; i++) {
                QTableWidgetItem* item = nullptr;
                double value = 0;

                item = _ui->tableWidget_MooRiv->item(i, 0);
                if (item)value = item->text().toDouble();
                else value = 0;
                _materialItem->setIsoMooneyRivlinC10(value, i);

                item = _ui->tableWidget_MooRiv->item(i, 1);
                if (item)value = item->text().toDouble();
                else value = 0;
                _materialItem->setIsoMooneyRivlinC01(value, i);

                item = _ui->tableWidget_MooRiv->item(i, 2);
                if (item)value = item->text().toDouble();
                else value = 0;
                _materialItem->setIsoMooneyRivlinD1(value, i);

                if (isTemp) {
                    item = _ui->tableWidget_MooRiv->item(i, 3);
                    if (item)value = item->text().toDouble();
                    else value = 0;
                }
                else value = 0;
                _materialItem->setIosMooneyRivlinTemperature(value, i);
            }
            break;
        }
        case 3:break;
        case 4:break;
        case 5:break;
        case 6:break;
        case 7:break;
        case 8:break;
        case 9:break;
        case 10:break;
        }
    }

    void MaterialHyperelasticWidget::saveValueAni()
    {
    }

    void MaterialHyperelasticWidget::initUi()
    {
        if (_materialItem == nullptr)return;

        //初始化Isotropic按钮
        QButtonGroup* group = new QButtonGroup();
        group->addButton(_ui->radioButton_Isotropic, 0);
        group->addButton(_ui->radioButton_Anisotropic, 1);
        group->setExclusive(true);
        _ui->radioButton_Isotropic->setChecked(true);
        _ui->radioButton_Isotropic->setEnabled(false);
        _ui->radioButton_Anisotropic->setEnabled(false);

        //初始化StrEnerPot下拉框
        QStringList isoStrEnerPotTypeList = {};
        isoStrEnerPotTypeList << tr("Arruda-Boyce") << tr("Marlow") << tr("Mooney-Rivlin") << tr("Neo Hooke") << tr("Ogden") << tr("Polynomial")
            << tr("ReducePolynomial") << tr("UsrDefined") << tr("VanderWaals") << tr("Yeoh") << tr("Unknown");
        _ui->comboBox_StrEnePot->addItems(isoStrEnerPotTypeList);
        _ui->comboBox_StrEnePot->setCurrentIndex(2);
        _ui->comboBox_StrEnePot->setEnabled(false);

        //初始化Coefficients按钮
        QButtonGroup* group1 = new QButtonGroup();
        group1->addButton(_ui->radioButton_TestData, 0);
        group1->addButton(_ui->radioButton_Coefficients, 1);
        group1->setExclusive(true);
        _ui->radioButton_TestData->setEnabled(false);
        _ui->radioButton_Coefficients->setChecked(true);
        _ui->radioButton_Coefficients->setEnabled(false);

        //初始化ModuliTimeScale控件
        QStringList isoModuliTimeScaleList = {};
        isoModuliTimeScaleList << tr("Long-term") << tr("Instantaneous");
        _ui->comboBox_ModTimeSca->addItems(isoModuliTimeScaleList);

        //初始化TableWidget
        _ui->tableWidget_MooRiv->addTableRowAndItem(0);
        //设置为单行模式
        _ui->tableWidget_MooRiv->setIsAloneRow(true);

        showValue();
    }

    void MaterialHyperelasticWidget::showValue()
    {
        //目前只支持各项异性（2024-06-19）
        _materialItem->setMaterialType(Interface::FITKAbaMaterialBehaviorEnum::HyereIsotropic);

        auto materialType = _materialItem->getMaterialType();
        switch (materialType) {
        case Interface::FITKAbaMaterialBehaviorEnum::HyereIsotropic: {
            _ui->radioButton_Isotropic->setChecked(true);
            showValueIso();
            break;
        }
        case Interface::FITKAbaMaterialBehaviorEnum::HyereAnisotropic: {
            _ui->radioButton_Isotropic->setChecked(false);
            break;
        }
        }
    }

    void MaterialHyperelasticWidget::showValueIsoCoefficients()
    {
        //目前只支持Mooney-Rivlin（2024-06-19）
        _materialItem->setIsoStrainEnergyPotential(Interface::FITKAbaMaterialBehaviorEnum::MooneyRivlin);

        auto strEnePotType = _materialItem->getIsoStrainEnergyPotential();
        switch (strEnePotType) {
        case Interface::FITKAbaMaterialBehaviorEnum::ArrudaBoyce:break;
        case Interface::FITKAbaMaterialBehaviorEnum::Marlow:break;
        case Interface::FITKAbaMaterialBehaviorEnum::MooneyRivlin: {
            _ui->comboBox_StrEnePot->setCurrentIndex(2);

            auto modTiemType = _materialItem->getIsoModuliTimeScale();
            switch (modTiemType) {
            case Interface::FITKAbaMaterialBehaviorEnum::LongTerm:_ui->comboBox_ModTimeSca->setCurrentIndex(0); break;
            case Interface::FITKAbaMaterialBehaviorEnum::Instantaneous:_ui->comboBox_ModTimeSca->setCurrentIndex(1); break;
            }

            //温度是否使用参数
            _ui->checkBox_Temp->setChecked(_materialItem->getUseTemperatureDependentData());
            changeMaterialTemp(strEnePotType, _materialItem->getUseTemperatureDependentData());
            //显示TableWidget中的数据
            showIsoTableValue(strEnePotType);

            break;
        }
        case Interface::FITKAbaMaterialBehaviorEnum::NeoHooke: break;
        case Interface::FITKAbaMaterialBehaviorEnum::Ogden: break;
        case Interface::FITKAbaMaterialBehaviorEnum::Polynomial: break;
        case Interface::FITKAbaMaterialBehaviorEnum::ReducePolynomial: break;
        case Interface::FITKAbaMaterialBehaviorEnum::UsrDefined: break;
        case Interface::FITKAbaMaterialBehaviorEnum::VanderWaals: break;
        case Interface::FITKAbaMaterialBehaviorEnum::Yeoh: break;
        case Interface::FITKAbaMaterialBehaviorEnum::Unknown:break;
        }
    }

    void MaterialHyperelasticWidget::showValueIso()
    {
        //目前只支持系数
        _materialItem->setIsoInputSource(Interface::FITKAbaMaterialBehaviorEnum::Coeffcients);

        auto inputSourceType = _materialItem->getIsoInputSource();
        switch (inputSourceType)
        {
        case Interface::FITKAbaMaterialBehaviorEnum::TestData:
            _ui->radioButton_TestData->setChecked(true);
            break;
        case Interface::FITKAbaMaterialBehaviorEnum::Coeffcients: {
            _ui->radioButton_Coefficients->setChecked(true);
            showValueIsoCoefficients();
            break;
        }
        }
    }

    void MaterialHyperelasticWidget::showIsoTableValue(Interface::FITKAbaMaterialBehaviorEnum::HyperelasticIsotropicStrainEnergyPotential type)
    {
        if (_materialItem == nullptr)return;
        bool isTemp = _materialItem->getUseTemperatureDependentData();

        switch (type) {
        case Interface::FITKAbaMaterialBehaviorEnum::ArrudaBoyce: break;
        case Interface::FITKAbaMaterialBehaviorEnum::Marlow: break;
        case Interface::FITKAbaMaterialBehaviorEnum::MooneyRivlin: {
            int rowNum = _materialItem->getIsoMooneyRivlinDataRows();
            for (int i = 0; i < rowNum; i++) {
                double value = 0;
                QTableWidgetItem* item = nullptr;

                item = new QTableWidgetItem(QString::number(_materialItem->getIsoMooneyRivlinC10(i)));
                _ui->tableWidget_MooRiv->setItem(i, 0, item);

                item = new QTableWidgetItem(QString::number(_materialItem->getIsoMooneyRivlinC01(i)));
                _ui->tableWidget_MooRiv->setItem(i, 1, item);

                item = new QTableWidgetItem(QString::number(_materialItem->getIsoMooneyRivlinD1(i)));
                _ui->tableWidget_MooRiv->setItem(i, 2, item);

                item = new QTableWidgetItem(QString::number(_materialItem->getIsoMooneyRivlinTemperature(i)));
                _ui->tableWidget_MooRiv->setItem(i, 3, item);
            }
        }
        case Interface::FITKAbaMaterialBehaviorEnum::NeoHooke: break;
        case Interface::FITKAbaMaterialBehaviorEnum::Ogden: break;
        case Interface::FITKAbaMaterialBehaviorEnum::Polynomial: break;
        case Interface::FITKAbaMaterialBehaviorEnum::ReducePolynomial:break;
        case Interface::FITKAbaMaterialBehaviorEnum::UsrDefined:break;
        case Interface::FITKAbaMaterialBehaviorEnum::VanderWaals:break;
        case Interface::FITKAbaMaterialBehaviorEnum::Yeoh: break;
        case Interface::FITKAbaMaterialBehaviorEnum::Unknown:break;
        }
    }

    void MaterialHyperelasticWidget::changeMaterialTemp(Interface::FITKAbaMaterialBehaviorEnum::HyperelasticIsotropicStrainEnergyPotential type, bool isTemp)
    {
        _ui->tableWidget_MooRiv->hideColumn(3);

        if (isTemp == false)return;
        switch (type) {
        case Interface::FITKAbaMaterialBehaviorEnum::ArrudaBoyce: break;
        case Interface::FITKAbaMaterialBehaviorEnum::Marlow: break;
        case Interface::FITKAbaMaterialBehaviorEnum::MooneyRivlin:_ui->tableWidget_MooRiv->showColumn(3); break;
        case Interface::FITKAbaMaterialBehaviorEnum::NeoHooke: break;
        case Interface::FITKAbaMaterialBehaviorEnum::Ogden: break;
        case Interface::FITKAbaMaterialBehaviorEnum::Polynomial: break;
        case Interface::FITKAbaMaterialBehaviorEnum::ReducePolynomial:break;
        case Interface::FITKAbaMaterialBehaviorEnum::UsrDefined:break;
        case Interface::FITKAbaMaterialBehaviorEnum::VanderWaals:break;
        case Interface::FITKAbaMaterialBehaviorEnum::Yeoh: break;
        case Interface::FITKAbaMaterialBehaviorEnum::Unknown:break;
        }
    }
}
